﻿using System;
using System.Net;
using System.IO;
using System.Diagnostics;
using System.Xml.Linq;
using System.Linq;
using System.Collections.Generic;
using System.Json;
using System.Windows;

namespace VisualStudioAchievements
{
    public delegate void HelperDelegate();

    public class NinerReader
    {
        Action<Niner> currentAction;

        public Niner CurrentNiner;

        public void GetNiner(string name, bool isInit, Action<Niner> action = null)
        {
            BindingPoint.Instance.HidePerfBar = false;

            if (action != null)
                currentAction = action;

            string compositeUrl = string.Empty;

            if (isInit)
            {
                CurrentNiner = new Niner();
                CurrentNiner.Alias = name;
                compositeUrl = string.Format(URLConstants.NinerProfile, CurrentNiner.Alias);
            }
            else
            {
                compositeUrl = string.Format(URLConstants.AllAchievements, CurrentNiner.Alias);
            }

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(compositeUrl);

            if (isInit)
            {
                request.BeginGetResponse(new AsyncCallback(CompleteRequest), request);
            }
            else
            {
                request.BeginGetResponse(new AsyncCallback(CompleteAchievementRequest), request);
            }
        }

        private void CompleteRequest(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            try
            {
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);

                string HTMLContent;
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    HTMLContent = reader.ReadToEnd();
                }

                GetNinerContent(HTMLContent);
            }
            catch
            {
                BindingPoint.Instance.HidePerfBar = true;
                App.MainPageDispatcher.BeginInvoke(new Action(() => MessageBox.Show("User not registered on Channel9: " + CurrentNiner.Alias)));
            }
        }

        private void GetNinerContent(string HTMLContent)
        {
            int location = HTMLContent.IndexOf("<div class=\"author\">");
            string stripped = HTMLContent.Substring(location, HTMLContent.Length - location);
            location = stripped.IndexOf("</div>");
            stripped = stripped.Substring(0, location+6);

            XDocument doc = XDocument.Parse(stripped);

            CurrentNiner.Name = (from c in doc.Root.Elements() where c.Name == "img" select c).FirstOrDefault().Attribute("alt").Value;

            string avatarUrl = (from c in doc.Root.Elements() where c.Name == "img" select c).FirstOrDefault().Attribute("src").Value;
            CurrentNiner.Avatar = new Uri(avatarUrl);

            string caption = (from c in doc.Root.Elements() where c.Name == "span" && c.Attribute("class").Value == "caption" select c).FirstOrDefault().Value;
            CurrentNiner.Caption = caption;

            GetNiner(CurrentNiner.Alias, false);
        }

        private void CompleteAchievementRequest(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            try
            {
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);

                string JSONContent;
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    JSONContent = reader.ReadToEnd();
                }

                CurrentNiner.Achievements = new List<Achievement>();

                System.Json.JsonValue obj = System.Json.JsonObject.Parse(JSONContent);
                JsonValue value = obj["Achievements"];

                foreach (JsonValue aValue in value)
                {
                    Achievement achievement = new Achievement();
                    achievement.Category = aValue["Category"];

                    try
                    {
                        DateTime dateEarned = new DateTime();
                        DateTime.TryParse(aValue["DateEarned"], out dateEarned);
                        achievement.DateEarned = dateEarned;
                        
                        achievement.Description = aValue["Description"];
                        achievement.FriendlyName = aValue["FriendlyName"];
                        achievement.Icon = new Uri(aValue["Icon"]);
                        achievement.IconSmall = new Uri(aValue["IconSmall"]);
                        achievement.Name = aValue["Name"];
                        string data = aValue["Points"];
                        achievement.Points = Convert.ToInt32(data);

                        CurrentNiner.Achievements.Add(achievement);

                        CurrentNiner.Points += achievement.Points;
                    }
                    catch (KeyNotFoundException)
                    {
                        // Do something else here. Eventually.
                        Debug.WriteLine("Achievement not earned");
                    }
                }

                App.MainPageDispatcher.BeginInvoke(new Action(() => currentAction(CurrentNiner)));
            }
            catch
            {
                App.MainPageDispatcher.BeginInvoke(new Action(() => MessageBox.Show("User not registered for achievements.")));
            }
            BindingPoint.Instance.HidePerfBar = true;
        }

    }
}
